package sharemem

import (
	"log"
	"server_cluster/common/protoc/pb"
	"server_cluster/common/tools"
	"server_cluster/battle/battle_config"
)

//
type ShmUser struct {
	index int32
	uid   int64
	fd    int32
	kill_time   int64				// 服务器清除用户时间，以服务端标准计时
	game_data	GameData
}

func (u *ShmUser) Meminit(index int32) {
	u.index = index
	u.uid = 0
	u.fd = 0
	u.kill_time = 0
	u.game_data.meminit()
}

func (u *ShmUser)GetIndex() int32 {
	return u.index
}

func (u *ShmUser)GetKillTime() int64 {
	return u.kill_time
}

func (u *ShmUser)SetKillTime() {
	u.kill_time = Myshm.Time_now + battle_config.FIGHT_TIME_MAX
}

func (u *ShmUser)GetFd() int32 {
	return u.fd
}

func (u *ShmUser)SetFd(fd int32) {
	u.fd = fd
}

func (u *ShmUser) IsUse() bool {
	return u.uid > 0
}

func (u *ShmUser) use(uid int64) {
	u.uid = uid
}

func (u *ShmUser) isMe(uid int64) bool {
	return u.uid == uid
}

func (u *ShmUser) GetId() int64 {
	return u.uid
}

func (u *ShmUser) GetBGId() int32 {
	return u.game_data.GetBid()
}

func (u *ShmUser) Clean_user() {
    if u.GetId() == 1234567 {
        return
    }
    index := u.index
    //Sem_wait(&(Myshm.Sem_user[index]))
    //清余索引
    u.DeleteShmUserAllMap()
    DeleteShmUserMap(u.GetId())
    //清理内存
    u.Meminit(index)
    Myshm.Stock++
    //Sem_post(&(Myshm.Sem_user[index]))
}

func (u *ShmUser) Get_action(index int32) *FightAction {
	if u.game_data.action_num <= 0 || index < 0 || index >= battle_config.FIGHT_ACTION_MAX {
		return nil
	}
	if !u.game_data.action[index].IsUse() {
		return nil
	}
	return &(u.game_data.action[index])
}

func (u *ShmUser) ResetAction() {
	u.game_data.ActionInit()
	u.SetKillTime()
}

func (u *ShmUser) CheckActionNum() bool {
	if u.game_data.action_num >= battle_config.FIGHT_ACTION_MAX*int32(u.game_data.fight_num) {
        return false
    }
	return true
}

func (u *ShmUser) SetAction(id int32,root_time int32,node_time int32,trigger_type int8,trigger int8,target_type int8,target int8,card int32,num int8) {
	u.game_data.action[u.game_data.action_num].id = id
	u.game_data.action[u.game_data.action_num].root_time = root_time
	u.game_data.action[u.game_data.action_num].node_time = node_time
	u.game_data.action[u.game_data.action_num].trigger_type = trigger_type
	u.game_data.action[u.game_data.action_num].trigger = trigger
	u.game_data.action[u.game_data.action_num].target_type = target_type
	u.game_data.action[u.game_data.action_num].target = target
	u.game_data.action[u.game_data.action_num].card = card
	u.game_data.action[u.game_data.action_num].num = num
	u.game_data.action_num++
}

func (u *ShmUser) CreateFight(fdata *pb.ServerUserFightData) uint16 {
	return u.game_data.CreateFight(fdata)
}

func (u *ShmUser)BuildBattleFight(b *Battle_area,index int8) bool {
    var i int8
    b.fight_index = index
    for i=0;i<BATTLE_MONSTER;i++ {
        b.monster[i] = u.game_data.ft[index].monster[i].Build(b)
    }
    return true
}

func (u *ShmUser)BuildBattleArea() *Battle_area {
	//随机种子
    tools.MySeed(int32(u.game_data.create_time%10000))
	log.Printf("seed = %v",u.game_data.create_time%10000)
    var i int8
    area := &Battle_area{
        shmUser_index:u.index,
        is_active:u.game_data.is_active,
        fight_num:u.game_data.fight_num,
        fight_index:0,
        action_index:0,
        card_num:0,
        draw_time:0,
        root_time:0,
        node_time:0,
		cd_time:0,
        real_time:0,
        end_time:u.game_data.end_time,
        rage_time:battle_config.RAGE_TIME,
		is_completed:false,
    }
	if u.game_data.captain_skill > 0 {
		area.captain_skill = Get_config_captain(u.game_data.captain_skill)
	}
    for i=0;i<BATTLE_ROLE;i++ {
        area.role[i] = u.game_data.role[i].Build(area)
    }
    for i=0;i<BATTLE_ROLE_ASSIST;i++ {
        area.role_assist[i] = u.game_data.role_assist[i].Build(area)
    }
	//
	bg := Get_config_battle_group(u.game_data.bid)
	if bg != nil {
		var i,j int8
		for i=0;i<BATTLE_PARAM_MAX1;i++ {
			tmp := make([]int32,0)
			for j=0;j<BATTLE_PARAM_MAX2;j++ {
				if bg.Condition[i][j] > 0 {
					tmp = append(tmp,bg.Condition[i][j])
				}
			}
			if len(tmp) <= 0 {
				continue
			}
			area.conditions = append(area.conditions,tmp)
		}
	}
	//初始化事件打点
    //游戏开始事件
    area.SetEventMap(area.root_time,0,0)
    //游戏结束事件
    area.SetEventMap(area.end_time,0,0)
    //恢复怒气事件
    area.SetEventMap(area.rage_time,0,0)
    //前端操作事件
    action := u.Get_action(area.action_index)
    if action != nil {
        area.SetEventMap(action.root_time,action.node_time,0)
    }
    return area
}

func (u *ShmUser)ActionParamCheck(id int32,root_time int32,node_time int32,trigger_type int8,trigger int8,target_type int8,target int8,card int32,num int8) bool {
    if id <= 0 || root_time < 0 || node_time < 0 || trigger_type <= 0 || trigger < 0 || target_type <= 0 || target < 0 || card <= 0 || num <= 0 {
        return false
    }
    if u.game_data.action_num == 0 {
        return true
    }
    if id <= u.game_data.action[u.game_data.action_num-1].id || root_time < u.game_data.action[u.game_data.action_num-1].root_time ||
    (root_time == u.game_data.action[u.game_data.action_num-1].root_time && node_time < u.game_data.action[u.game_data.action_num-1].node_time) {
        return false
    }
    return true
}

func (u *ShmUser)GetBattleGroupId() int32 {
	return u.game_data.bid
}

func (u *ShmUser)BattleCheck(res *pb.ServerUserFightData) bool {
    //用shm数据生成临时战场
    bt := u.BuildBattleArea()
    if bt == nil {
        log.Printf("build battle area error.user = %d",u.GetId())
        return false
    }
	if !u.RunBattle(bt) {
        log.Printf("user %d game over.",u.GetId())
		return false
	}
    //战斗胜利
    //打包战斗组id和所有上阵角色属性
	/*
    for i=0;i<BATTLE_ROLE;i++ {
        if !bt.role[i].Exist() {
            continue
        }
        base := &pb.BaseInfo{}
        for k,v := range bt.role[i].GetAtMap() {
            attr := &pb.Attr{
                Id:k,
                Val:v.val,
            }
            base.Attr = append(base.Attr,attr)
        }
        res.FightRole = append(res.FightRole,base)
    }*/
	return true
}

func (u *ShmUser)RunBattle(bt *Battle_area) bool {
    var i,ret int8

	ret = 0
    for i=0;i<bt.fight_num;i++ {
        if !u.game_data.ft[i].IsUse() {
            break
        }
        //生成战场中怪物
        if !u.BuildBattleFight(bt,i) {
            log.Printf("build battle fight error fid=%d",u.game_data.ft[i].fid)
        }
        //事件打点
        bt.SetEventMap(bt.root_time,0,0)
		if i == 0 {
			//游戏开始触发被动
			bt.DoPassive(0)
		}
        //战斗运行
		ret = bt.RunFight()
		if ret != 4 {
			break
		}
    }
	bt.is_completed = true
	log.Printf("run fight ret = %v",ret)
	switch ret {
		case 2:
		case 4:
			return bt.CheckConditions(true,bt.conditions,nil,nil)
		default:
			return false
	}
	log.Printf("战斗胜利")
    return true
}
